package summary;

import java.util.Iterator;
import java.util.Vector;


public class Analyzer {	
		
	private long MINSECOND;
	private long MAXSECOND;
	
	Vector<InstantData> data;	
	Vector<InstantStatistics> statistics = new Vector<InstantStatistics>();
	ReferenceStatistics refStatistics;
	GradientStatistics gradientStatistics;
		
	long maxGlobalSkew = 0;
	long maxLocalSkew = 0;
	long maxAvgGlobalSkew = 0;
	long maxAvgLocalSkew = 0;
	long avgAvgGlobalSkew = 0;
	long avgAvgLocalSkew = 0;
	
	public Analyzer(Vector<InstantData> data,int topology,int numNodes,long intervalStart,long intervalEnd){
		MINSECOND = intervalStart;
		MAXSECOND = intervalEnd;
		this.data = data;	
		analyzeSkews(topology);
		refStatistics = new ReferenceStatistics(data,numNodes,intervalStart,intervalEnd);
		gradientStatistics = new GradientStatistics(data,numNodes,intervalStart,intervalEnd,topology);
		summary();
	}	
	
	public Vector<InstantStatistics> getSkews(){
		return statistics;
	}
	
	public ReferenceStatistics getReferenceStatistics(){
		return refStatistics;
	}
	
	public GradientStatistics getGraidentStatistics(){
		return gradientStatistics;
	}
	
	public long getMaxGlobalSkew() {
		return maxGlobalSkew;
	}

	public long getMaxLocalSkew() {
		return maxLocalSkew;
	}

	public long getMaxAvgGlobalSkew() {
		return maxAvgGlobalSkew;
	}

	public long getMaxAvgLocalSkew() {
		return maxAvgLocalSkew;
	}
	
	public long getAvgAvgGlobalSkew() {
		return avgAvgGlobalSkew;
	}

	public long getAvgAvgLocalSkew() {
		return avgAvgLocalSkew;
	}
	
	private void analyzeSkews(int topology){
		
		for (Iterator<InstantData> iterator = data.iterator(); iterator.hasNext();) {
			InstantData syncData = (InstantData) iterator.next();
			
			if(syncData.second <= MAXSECOND && syncData.second >= MINSECOND){
				InstantStatistics statistic = new InstantStatistics(syncData,topology);
				statistics.add(statistic);				
			}
		}
	}		
		
	private void  summary(){
		
		long maxGlobal = 0;
		long maxLocal = 0;
		long maxAvgGlobal = 0;
		long maxAvgLocal = 0;
		long avgAvgLocal = 0;
		long avgAvgGlobal = 0;
		long n= 0;
		
		for (Iterator<InstantStatistics> iterator = statistics.iterator(); iterator.hasNext();) {
			InstantStatistics data = (InstantStatistics) iterator.next();
			
			if(data.second < MINSECOND || data.second > MAXSECOND) 
				continue;
						
			if(data.maxGlobalSkew > maxGlobal){
				maxGlobal = data.maxGlobalSkew;
			}
				
			if(data.avgGlobalSkew > maxAvgGlobal){
				maxAvgGlobal = data.avgGlobalSkew;
			}				
				
			if(data.maxLocalSkew>maxLocal){
				maxLocal = data.maxLocalSkew;
			}
				
			if(data.avgLocalSkew>maxAvgLocal){
				maxAvgLocal = data.avgLocalSkew;
			}				
				
			avgAvgGlobal += data.avgGlobalSkew;
			avgAvgLocal  += data.avgLocalSkew;
			n++;
		}
		
		System.out.println("Maximum global skew:" + maxGlobal);
		System.out.println("Maximum average global skew:" + maxAvgGlobal);
		System.out.println("Maximum local skew:" + maxLocal);
		System.out.println("Maximum average local skew:" + maxAvgLocal);
		
		if(n>0){
			System.out.println("Average average global skew:" + avgAvgGlobal/n);
			System.out.println("Average average local skew:" + avgAvgLocal/n);
		}
		
		this.maxGlobalSkew = maxGlobal;
		this.maxLocalSkew = maxLocal;
		this.maxAvgLocalSkew = maxAvgLocal;
		this.maxAvgGlobalSkew = maxAvgGlobal;
		this.avgAvgGlobalSkew = avgAvgGlobal/n;
		this.avgAvgLocalSkew = avgAvgLocal/n;
	}
	
	public Vector<NeighborInstantStatistics> getNeighborInstantSkews(int id1,int id2){
		Vector<NeighborInstantStatistics> neighbors = new Vector<NeighborInstantStatistics>();
		for (Iterator<InstantData> iterator = data.iterator(); iterator.hasNext();) {
			InstantData syncData = (InstantData) iterator.next();
			 neighbors.add(new NeighborInstantStatistics(syncData, id1, id2));
			
		}
		
		return neighbors;
	}
	
}
